package java.lang;

public final class Byte extends Number implements Comparable<Byte> {

	/**
	 * The minimum value a <code>byte</code> can represent is -128 (or
	 * -2<sup>7</sup>).
	 */
	public static final byte MIN_VALUE = -128;

	/**
	 * The maximum value a <code>byte</code> can represent is 127 (or
	 * 2<sup>7</sup> - 1).
	 */
	public static final byte MAX_VALUE = 127;

	/**
	 * The number of bits needed to represent a <code>byte</code>.
	 * 
	 * @since 1.5
	 */
	public static final int SIZE = 8;

	// This caches Byte values, and is used by boxing conversions via
	// valueOf(). We're required to cache all possible values here.
	private static Byte[] byteCache = new Byte[MAX_VALUE - MIN_VALUE + 1];
	static {
		for (int i = MIN_VALUE; i <= MAX_VALUE; i++)
			byteCache[i - MIN_VALUE] = new Byte((byte) i);
	}

	/**
	 * The immutable value of this Byte.
	 * 
	 * @serial the wrapped byte
	 */
	private final byte value;

	/**
	 * Create a <code>Byte</code> object representing the value of the
	 * <code>byte</code> argument.
	 * 
	 * @param value
	 *            the value to use
	 */
	public Byte(byte value) {
		this.value = value;
	}

	/**
	 * Create a <code>Byte</code> object representing the value specified by the
	 * <code>String</code> argument
	 * 
	 * @param s
	 *            the string to convert
	 * @throws NumberFormatException
	 *             if the String does not contain a byte
	 * @see #valueOf(String)
	 */
	public Byte(String s) {
		value = parseByte(s, 10);
	}

	/**
	 * Converts the <code>byte</code> to a <code>String</code> and assumes a
	 * radix of 10.
	 * 
	 * @param b
	 *            the <code>byte</code> to convert to <code>String</code>
	 * @return the <code>String</code> representation of the argument
	 */
	public static String toString(byte b) {
		return String.valueOf(b);
	}

	/**
	 * Converts the specified <code>String</code> into a <code>byte</code>. This
	 * function assumes a radix of 10.
	 * 
	 * @param s
	 *            the <code>String</code> to convert
	 * @return the <code>byte</code> value of <code>s</code>
	 * @throws NumberFormatException
	 *             if <code>s</code> cannot be parsed as a <code>byte</code>
	 * @see #parseByte(String)
	 */
	public static byte parseByte(String s) {
		return parseByte(s, 10);
	}

	/**
	 * Converts the specified <code>String</code> into an <code>int</code> using
	 * the specified radix (base). The string must not be <code>null</code> or
	 * empty. It may begin with an optional '-', which will negate the answer,
	 * provided that there are also valid digits. Each digit is parsed as if by
	 * <code>Character.digit(d, radix)</code>, and must be in the range
	 * <code>0</code> to <code>radix - 1</code>. Finally, the result must be
	 * within <code>MIN_VALUE</code> to <code>MAX_VALUE</code>, inclusive.
	 * Unlike Double.parseDouble, you may not have a leading '+'.
	 * 
	 * @param s
	 *            the <code>String</code> to convert
	 * @param radix
	 *            the radix (base) to use in the conversion
	 * @return the <code>String</code> argument converted to <code>byte</code>
	 * @throws NumberFormatException
	 *             if <code>s</code> cannot be parsed as a <code>byte</code>
	 */
	public static byte parseByte(String s, int radix) {
		int i = Integer.parseInt(s, radix, false);
		if ((byte) i != i)
			throw new NumberFormatException();
		return (byte) i;
	}

	/**
	 * Creates a new <code>Byte</code> object using the <code>String</code> and
	 * specified radix (base).
	 * 
	 * @param s
	 *            the <code>String</code> to convert
	 * @param radix
	 *            the radix (base) to convert with
	 * @return the new <code>Byte</code>
	 * @throws NumberFormatException
	 *             if <code>s</code> cannot be parsed as a <code>byte</code>
	 * @see #parseByte(String, int)
	 */
	public static Byte valueOf(String s, int radix) {
		return valueOf(parseByte(s, radix));
	}

	/**
	 * Creates a new <code>Byte</code> object using the <code>String</code>,
	 * assuming a radix of 10.
	 * 
	 * @param s
	 *            the <code>String</code> to convert
	 * @return the new <code>Byte</code>
	 * @throws NumberFormatException
	 *             if <code>s</code> cannot be parsed as a <code>byte</code>
	 * @see #Byte(String)
	 * @see #parseByte(String)
	 */
	public static Byte valueOf(String s) {
		return valueOf(parseByte(s, 10));
	}

	/**
	 * Returns a <code>Byte</code> object wrapping the value. In contrast to the
	 * <code>Byte</code> constructor, this method will cache some values. It is
	 * used by boxing conversion.
	 * 
	 * @param val
	 *            the value to wrap
	 * @return the <code>Byte</code>
	 */
	public static Byte valueOf(byte val) {
		return byteCache[val - MIN_VALUE];
	}

	/**
	 * Convert the specified <code>String</code> into a <code>Byte</code>. The
	 * <code>String</code> may represent decimal, hexadecimal, or octal numbers.
	 * 
	 * <p>
	 * The extended BNF grammar is as follows:<br>
	 * 
	 * <pre>
	 * <em>DecodableString</em>:
	 *      ( [ <code>-</code> ] <em>DecimalNumber</em> )
	 *    | ( [ <code>-</code> ] ( <code>0x</code> | <code>0X</code>
	 *              | <code>#</code> ) { <em>HexDigit</em> }+ )
	 *    | ( [ <code>-</code> ] <code>0</code> { <em>OctalDigit</em> } )
	 * <em>DecimalNumber</em>:
	 *        <em>DecimalDigit except '0'</em> { <em>DecimalDigit</em> }
	 * <em>DecimalDigit</em>:
	 *        <em>Character.digit(d, 10) has value 0 to 9</em>
	 * <em>OctalDigit</em>:
	 *        <em>Character.digit(d, 8) has value 0 to 7</em>
	 * <em>DecimalDigit</em>:
	 *        <em>Character.digit(d, 16) has value 0 to 15</em>
	 * </pre>
	 * 
	 * Finally, the value must be in the range <code>MIN_VALUE</code> to
	 * <code>MAX_VALUE</code>, or an exception is thrown.
	 * 
	 * @param s
	 *            the <code>String</code> to interpret
	 * @return the value of the String as a <code>Byte</code>
	 * @throws NumberFormatException
	 *             if <code>s</code> cannot be parsed as a <code>byte</code>
	 * @throws NullPointerException
	 *             if <code>s</code> is null
	 * @see Integer#decode(String)
	 */
	public static Byte decode(String s) {
		int i = Integer.parseInt(s, 10, true);
		if ((byte) i != i)
			throw new NumberFormatException();
		return valueOf((byte) i);
	}

	/**
	 * Return the value of this <code>Byte</code>.
	 * 
	 * @return the byte value
	 */
	public byte byteValue() {
		return value;
	}

	/**
	 * Return the value of this <code>Byte</code> as a <code>short</code>.
	 * 
	 * @return the short value
	 */
	public short shortValue() {
		return value;
	}

	/**
	 * Return the value of this <code>Byte</code> as an <code>int</code>.
	 * 
	 * @return the int value
	 */
	public int intValue() {
		return value;
	}

	/**
	 * Return the value of this <code>Byte</code> as a <code>long</code>.
	 * 
	 * @return the long value
	 */
	public long longValue() {
		return value;
	}

	/**
	 * Return the value of this <code>Byte</code> as a <code>float</code>.
	 * 
	 * @return the float value
	 */
	public float floatValue() {
		return value;
	}

	/**
	 * Return the value of this <code>Byte</code> as a <code>double</code>.
	 * 
	 * @return the double value
	 */
	public double doubleValue() {
		return value;
	}

	/**
	 * Converts the <code>Byte</code> value to a <code>String</code> and assumes
	 * a radix of 10.
	 * 
	 * @return the <code>String</code> representation of this <code>Byte</code>
	 * @see Integer#toString()
	 */
	public String toString() {
		return String.valueOf(value);
	}

	/**
	 * Return a hashcode representing this Object. <code>Byte</code>'s hash code
	 * is simply its value.
	 * 
	 * @return this Object's hash code
	 */
	public int hashCode() {
		return value;
	}

	/**
	 * Returns <code>true</code> if <code>obj</code> is an instance of
	 * <code>Byte</code> and represents the same byte value.
	 * 
	 * @param obj
	 *            the object to compare
	 * @return whether these Objects are semantically equal
	 */
	public boolean equals(Object obj) {
		return obj instanceof Byte && value == ((Byte) obj).value;
	}

	/**
	 * Compare two Bytes numerically by comparing their <code>byte</code>
	 * values. The result is positive if the first is greater, negative if the
	 * second is greater, and 0 if the two are equal.
	 * 
	 * @param b
	 *            the Byte to compare
	 * @return the comparison
	 * @since 1.2
	 */
	public int compareTo(Byte b) {
		return value - b.value;
	}

}
